#include "beamactor.h"
#include "resourceloader.h"

static const char beam_in_vert[] =
	"uniform float time;\n"
	"void main(void)\n"
	"{\n"
		"gl_Position = ftransform();\n"
		"vec4 texco = gl_MultiTexCoord0;\n"
		//"texco.s = texco.s + time*0.06;\n"
		"texco.t = texco.t + time*0.02;\n"
		"gl_TexCoord[0] = texco;\n"
	"}\n";

static const char beam_in_frag[] =
	"uniform sampler2D TextureU;\n"
	"void main (void)\n"
	"{\n"
		"vec4 color = texture2D(TextureU,gl_TexCoord[0].st);\n"
		"gl_FragColor = color;\n"
	"}\n";

static const char beam_out_vert[] =
	"uniform float time;\n"
	"void main(void)\n"
	"{\n"
		"gl_Position = ftransform();\n"
		"vec4 texco = gl_MultiTexCoord0;\n"
		"texco.s = texco.s - time*0.01;\n"
		"texco.t = texco.t + time*0.01;\n"
		"gl_TexCoord[0] = texco;\n"
	"}\n";

static const char beam_out_frag[] =
	"uniform sampler2D TextureU;\n"
	"void main (void)\n"
	"{\n"
		"vec4 color = texture2D(TextureU,gl_TexCoord[0].st);\n"
		"gl_FragColor = color;\n"
	"}\n";

namespace VrDataCore
{
	BeamActor::BeamActor()
	{}

	BeamActor::~BeamActor()
	{}

	void BeamActor::createDrawable()
	{
		_drawable = new CoreBase::Transformable(this);
		
		_billboard = new osg::Billboard();
		_billboard->setMode(osg::Billboard::AXIAL_ROT);
		_billboard->setAxis(osg::Vec3(0.0f,0.0f,1.0f));
		osg::Vec3Array* inarray = new osg::Vec3Array();
		inarray->push_back(osg::Vec3(-105,0.0,-10));
		inarray->push_back(osg::Vec3(105,0.0,-10));
		inarray->push_back(osg::Vec3(105,0.0,700));
		inarray->push_back(osg::Vec3(-105,0.0,700));
		osg::Geometry* geometry = new osg::Geometry();
		geometry->setVertexArray(inarray);
		osg::ref_ptr<osg::Vec2Array> coord = new osg::Vec2Array();
		coord->push_back(osg::Vec2(0.0f,0.0f));
		coord->push_back(osg::Vec2(1.0f,0.0f));
		coord->push_back(osg::Vec2(1.0f,1.0f));
		coord->push_back(osg::Vec2(0.0f,1.0f));
		geometry->setTexCoordArray(0,coord.get());
		osg::Vec4Array* colorArray = new osg::Vec4Array;
		colorArray->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f) );
		geometry->setColorArray( colorArray);
		geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
		geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
		_billboard->addDrawable(geometry,osg::Vec3(0,0,0));
		_drawable->getOSGNode()->asGroup()->addChild(_billboard);

		if(!_uniformInCallback.valid())
		{
			_uniformInCallback = new BeamCallback;
		}
		_uniformInCallback->reset();
		osg::ref_ptr<osg::StateSet> inss = geometry->getOrCreateStateSet();
		inss->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
		inss->setMode(GL_BLEND, osg::StateAttribute::ON);
		inss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
		QString in_image = "\\scenetextures\\billboard\\beamin.png";
		osg::ref_ptr<osg::Texture2D> tex = CoreBase::ResourceLoader::GetInstance().getTextureByFileName(in_image);
		tex->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
		tex->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);
		//tex->setWrap(osg::Texture::WRAP_R, osg::Texture::REPEAT);
		//tex->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR);
		//tex->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
		inss->setTextureAttributeAndModes(0,tex,osg::StateAttribute::ON);

		osg::ref_ptr<osg::Program> inprogram = new osg::Program;
		inprogram->setName("BeamActor In Program");
		osg::Shader *inVert = new osg::Shader(osg::Shader::VERTEX,beam_in_vert);
		osg::Shader *inFrag = new osg::Shader(osg::Shader::FRAGMENT,beam_in_frag);
		inprogram->addShader(inVert);
		inprogram->addShader(inFrag);
		inss->setAttributeAndModes(inprogram.get(), osg::StateAttribute::ON |osg::StateAttribute::PROTECTED);

		osg::Uniform* param2 = new osg::Uniform("time",0.0f);
		param2->setUpdateCallback(_uniformInCallback);
		inss->addUniform(param2);
		osg::Uniform* param3 = new osg::Uniform("TextureU",0);
		inss->addUniform(param3);

		_outDrawable = new CoreBase::CommonCylinder(this);
		_outDrawable->setCylinderSetting(100,36,osg::Vec3(0,0,-10),700,osg::Vec4(1,0,0,1),false,false,true);
		if(!_uniformOutCallback.valid())
		{
			_uniformOutCallback = new BeamCallback;
		}
		_uniformOutCallback->reset();
		_drawable->getOSGNode()->asGroup()->addChild(_outDrawable->getOSGNode());
		osg::ref_ptr<osg::StateSet> outss = _outDrawable->getOrCreateCenterStateSet();
		outss->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
		outss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
		QString out_image = "\\scenetextures\\billboard\\beamout.png";
		osg::ref_ptr<osg::Texture2D> outtex = CoreBase::ResourceLoader::GetInstance().getTextureByFileName(out_image);
		outtex->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
		outtex->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);
		outss->setTextureAttributeAndModes(0,outtex,osg::StateAttribute::ON);
		outss->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
		outss->setMode(GL_BLEND, osg::StateAttribute::ON );
		osg::ref_ptr<osg::Program> outprogram = new osg::Program;
		outprogram->setName("BeamActor Out Program");
		osg::Shader *outVert = new osg::Shader(osg::Shader::VERTEX,beam_out_vert);
		osg::Shader *outFrag = new osg::Shader(osg::Shader::FRAGMENT,beam_out_frag);
		outprogram->addShader(outVert);
		outprogram->addShader(outFrag);
		outss->setAttributeAndModes(outprogram.get(), osg::StateAttribute::ON |osg::StateAttribute::PROTECTED);
		osg::Uniform* framestateuniform = new osg::Uniform("time",0.0f);
		framestateuniform->setUpdateCallback(_uniformOutCallback);
		outss->addUniform(framestateuniform);

		/*_centerDrawable = new CoreBase::CommonCylinder(this);
		_centerDrawable->setCylinderSetting(100,36,osg::Vec3(0,0,-10),700,osg::Vec4(1,0,0,1),false,false,true);
		if(!_uniformcenterCallback.valid())
		{
			_uniformcenterCallback = new BeamCallback;
		}
		_uniformcenterCallback->reset();
		_drawable->getOSGNode()->asGroup()->addChild(_centerDrawable->getOSGNode());
		osg::ref_ptr<osg::StateSet> centerss = _centerDrawable->getOrCreateCenterStateSet();
		centerss->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
		centerss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
		QString center_image = "\\scenetextures\\billboard\\beamcenter.png";
		osg::ref_ptr<osg::Texture2D> centertex = CoreBase::ResourceLoader::GetInstance().getTextureByFileName(center_image);
		centertex->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
		centertex->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);
		centerss->setTextureAttributeAndModes(0,centertex,osg::StateAttribute::ON);
		centerss->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
		centerss->setMode(GL_BLEND, osg::StateAttribute::ON );
		osg::ref_ptr<osg::Program> centerprogram = new osg::Program;
		centerprogram->setName("BeamActor Center Program");
		osg::Shader *centerVert = new osg::Shader(osg::Shader::VERTEX,beam_out_vert);
		osg::Shader *centerFrag = new osg::Shader(osg::Shader::FRAGMENT,beam_out_frag);
		centerprogram->addShader(centerVert);
		centerprogram->addShader(centerFrag);
		centerss->setAttributeAndModes(centerprogram.get(), osg::StateAttribute::ON |osg::StateAttribute::PROTECTED);
		osg::Uniform* cframestateuniform = new osg::Uniform("time",0.0f);
		cframestateuniform->setUpdateCallback(_uniformcenterCallback);
		centerss->addUniform(cframestateuniform);*/
	}

	void BeamActor::buildPropertyMap()
	{}
}